package com.itany.nmms.service.Impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itany.nmms.constant.DictConstant;
import com.itany.nmms.dao.ProductMapper;
import com.itany.nmms.dao.SequenceMapper;
import com.itany.nmms.entity.*;
import com.itany.nmms.exception.FileUploadErrorException;
import com.itany.nmms.exception.ProductExistException;
import com.itany.nmms.exception.ProductTypeExistException;
import com.itany.nmms.exception.RequestParameterErrorException;
import com.itany.nmms.service.ProductService;
import com.itany.nmms.util.ParameterUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author 黄衡熙
 * @version 1.0
 */
@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public class ProductServiceImpl implements ProductService {
    @Autowired
    private SequenceMapper sequenceMapper;
    @Autowired
    private ProductMapper productMapper;
    @Override
    public void addProduct(String name, String price, String description, CommonsMultipartFile file, String typeId, HttpSession session) throws RequestParameterErrorException, ProductTypeExistException, FileUploadErrorException {
//        非空校验
        if(ParameterUtil.isNull(name)||ParameterUtil.isNull(price)||ParameterUtil.isNull(description)||file.isEmpty()||ParameterUtil.isNull(typeId)){
            throw new RequestParameterErrorException("请求参数有误");
        }
//        同一种商品类型的名称不能重复
        ProductExample example=new ProductExample();
        example.or()
                .andNameEqualTo(name)
                .andProductTypeIdEqualTo(Integer.parseInt(typeId));
        List<Product> products=productMapper.selectByExample(example);
        if(!products.isEmpty()){
            throw new ProductTypeExistException("商品已经存在");
        }

//        商品添加
        Product product=new Product();
        product.setName(name);
        product.setPrice(Double.parseDouble(price));
        product.setDescription(description);
        product.setProductTypeId(Integer.parseInt(typeId));


//        生成商品编号,根据标志位的值进行查询
        SequenceExample sequenceExample = new SequenceExample();
        sequenceExample.or()
//                商品编号前缀
                .andNameEqualTo(DictConstant.PRODUCT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(sequenceExample);
//查询两种情况，
        if(sequences.isEmpty()){
            // 未生成过，创建一组商品编号序列号的初始值数据
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.PRODUCT_NO_PREFIX);
//            初始值
            sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            sequenceMapper.insertSelective(sequence);


//生成商品编号
            // 编号由三部分组成:标志位+年月日+序列号
            product.setNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date()) + sequence.getValue());
        }else{
//            查到了且只有一条
            Sequence sequence=sequences.get(0);
//            判断其值是否达到最大,取值sequence.getValue()
            if(DictConstant.PRODUCT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())){
//                设置为初始值
                sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            }else{
//                下一个值加一保持格式不变，做一个工具类实现
                sequence.setValue(ParameterUtil.nextValue(sequence.getValue()));
            }
            sequenceMapper.updateByPrimaryKeySelective(sequence);
            product.setNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date()) + sequence.getValue());
        }



//        上传商品图片
//        取向对路径
        String path=DictConstant.PRODUCT_IMAGE_ROOT_FOLDER+new SimpleDateFormat("yyyyMMdd").format(new Date());
//        绝对路径
        String cp=session.getServletContext().getRealPath(path);
//        创建目录
        File f=new File(cp);
        f.mkdirs();
//        设置图片的属性值，其值为相对路径+文件名
        product.setImage(path+File.separator+file.getOriginalFilename());

//        上传图片
        try {
            //            添加商品,需先添加商品，否则会导致图片传了无商品
            productMapper.insertSelective(product);//会回滚
            file.transferTo(new File(cp,file.getOriginalFilename()));//不会回滚
        } catch (IOException e) {
            throw new FileUploadErrorException("上传商品图片出错");
        }

    }

//    分页查询
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public PageInfo<Product> findPage(String pageNo, String pageSize) {
        if(ParameterUtil.isNull(pageNo)){
            pageNo=DictConstant.PRODUCT_TYPE_DEFAULT_PAGE_NO;
        }
        if (ParameterUtil.isNull(pageSize)){
            pageSize=DictConstant.PRODUCT_TYPE_DEFAULT_PAGE_SIZE;
        }
    PageHelper.startPage(Integer.parseInt(pageNo),Integer.parseInt(pageSize));
//        List<Product> products=productMapper.selectByExample(new ProductExample());
        List<Product> products = productMapper.selectAll();
        PageInfo<Product> productPage=new PageInfo<>(products);

//        删除操作时 当前页没有数据且不是第一页，则回退到上一页
        if(!"1".equals(pageNo) && productPage.getList().isEmpty()){
            Integer page=Integer.parseInt(pageNo)-1;
            productPage=findPage(page+"",pageSize);
        }
        return productPage;
    }

@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
@Override
    public Product findById(String id) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        return productMapper.selectByPrimaryKey(Integer.parseInt(id));
}

    @Override
    public void modifyProduct(String id, String name, String price, String description, CommonsMultipartFile file, String typeId, HttpSession session) throws RequestParameterErrorException, ProductExistException, FileUploadErrorException {
        if(ParameterUtil.isNull(id) || ParameterUtil.isNull(name) || ParameterUtil.isNull(price) || ParameterUtil.isNull(description) || ParameterUtil.isNull(typeId)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        ProductExample example = new ProductExample();
        example.or()
                .andNameEqualTo(name)
                .andProductTypeIdEqualTo(Integer.parseInt(typeId))
                .andIdNotEqualTo(Integer.parseInt(id));
        List<Product> products = productMapper.selectByExample(example);
        if(!products.isEmpty()){
            throw new ProductExistException("该类型的商品已经存在");
        }
        Product product = new Product();
        product.setId(Integer.parseInt(id));
        product.setName(name);
        product.setPrice(Double.parseDouble(price));
        product.setDescription(description);
        product.setProductTypeId(Integer.parseInt(typeId));


        if(file.isEmpty()){
//            未上传图片的直接执行修改操作
            productMapper.updateByPrimaryKeySelective(product);
        }else{
//            存在图片需要修改，原来的图片要删掉，获取原图片地址
            Product p=productMapper.selectByPrimaryKey(Integer.parseInt(id));
            String cp=session.getServletContext().getRealPath(p.getImage());
            File f=new File(cp);
//            删除原有
            f.delete();

//            上传新的图片
            String path=DictConstant.PRODUCT_IMAGE_ROOT_FOLDER+new SimpleDateFormat("yyyyMMdd").format(new Date());
//            获取基于服务器根目录的绝对路径
            cp=session.getServletContext().getRealPath(path);
//            创建目录
            File f2=new File(cp);
            f2.mkdirs();

            product.setImage(path+File.separator+file.getOriginalFilename());

            try {
                // 修改商品信息
                productMapper.updateByPrimaryKeySelective(product);

                // 上传商品图片
                file.transferTo(new File(cp, file.getOriginalFilename()));
            } catch (IOException e) {
                throw new FileUploadErrorException("上传商品图片失败");
            }
        }


    }

    @Override
    public void deleteById(String id, HttpSession session) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        Product p=productMapper.selectByPrimaryKey(Integer.parseInt(id));
        String cp=session.getServletContext().getRealPath(p.getImage());
        File f=new File(cp);
        productMapper.deleteByPrimaryKey(Integer.parseInt(id));
        f.delete();
    }

}
